package es.udc.fbellas.j2ee.tiendaweb.model.lineapedido.DAO;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import es.udc.fbellas.j2ee.tiendaweb.model.categoria.DAO.SQLCategoriaDAO;
import es.udc.fbellas.j2ee.tiendaweb.model.categoria.DAO.SQLCategoriaDAOFactory;
import es.udc.fbellas.j2ee.tiendaweb.model.categoria.TO.CategoriaTO;
import es.udc.fbellas.j2ee.tiendaweb.model.lineapedido.TO.LineaPedidoTO;
import es.udc.fbellas.j2ee.tiendaweb.model.producto.TO.ProductoTO;
import es.udc.fbellas.j2ee.util.exceptions.InstanceNotFoundException;
import es.udc.fbellas.j2ee.util.exceptions.InternalErrorException;
import es.udc.fbellas.j2ee.util.sql.GeneralOperations;

/**
 * An implementation of <code>SQLAccountDAO</code> for databases providing
 * counter columns with JDBC 3 drivers.
 */
public class SQLLineaPedidoDAO {
    
//
//si existe una linea de pedido
//

    public boolean exists(Connection connection, int idLineaPedido) 
        throws InternalErrorException {
        
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {

            /* Create "preparedStatement". */
            String queryString = "SELECT IDLINEA FROM LINEAPEDIDO WHERE IDLINEA = ?";
            preparedStatement = connection.prepareStatement(queryString);
            
            /* Fill "preparedStatement". */
            int i = 1;
            preparedStatement.setInt(i++, idLineaPedido);
            
            /* Execute query. */
            resultSet = preparedStatement.executeQuery();

            return resultSet.next();
            
        } catch (SQLException e) {
            throw new InternalErrorException(e);    
        } finally {
            GeneralOperations.closeResultSet(resultSet);
            GeneralOperations.closeStatement(preparedStatement);
        }
        
    }

//
//crea una nueva linea de pedido
//

	public LineaPedidoTO create(Connection connection, LineaPedidoTO lineaPedidoTO) 
        throws InternalErrorException {
        
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
    
        try {
                
            /* Create "preparedStatement". */
            String queryString = "INSERT INTO LINEAPEDIDO" +
                " (IDPEDIDO,NUMUNIDADES,PRECIO,ESTADO,IDPRODUCTO) VALUES (?,?,?,?,?)";
            preparedStatement = connection.prepareStatement(queryString,
                Statement.RETURN_GENERATED_KEYS);    
            
            /* Fill "preparedStatement". */
            int i = 1;
            preparedStatement.setInt(i++, lineaPedidoTO.getIdPedido());
//            preparedStatement.setInt(i++, lineaPedidoTO.getIdLinea());
            preparedStatement.setInt(i++, lineaPedidoTO.getNumUnidades());
            preparedStatement.setInt(i++, lineaPedidoTO.getPrecio());
            preparedStatement.setString(i++, lineaPedidoTO.getEstadoLinea());
            preparedStatement.setInt(i++, lineaPedidoTO.getIdProducto());

                        
            /* Execute query. */
            int insertedRows = preparedStatement.executeUpdate();
        
            if (insertedRows == 0) {
                throw new SQLException("No se ha podido anhadir la linea de pedido");
            }

            if (insertedRows > 1) {
                throw new SQLException("Tupla duplicada en la tabla LINEAPEDIDO");
            }
            
            /* Get account identifier. */
            resultSet = preparedStatement.getGeneratedKeys();

            if (!resultSet.next()) {
                throw new InternalErrorException(new SQLException(
                    "JDBC driver did not return generated key."));
            }
            
			int identificador = resultSet.getInt(1);

            /* Return the value object. */
            return new LineaPedidoTO(lineaPedidoTO.getIdPedido(),identificador, lineaPedidoTO.getNumUnidades(), lineaPedidoTO.getPrecio(), lineaPedidoTO.getEstadoLinea(), lineaPedidoTO.getIdProducto());
        
        } catch (SQLException e) {
            throw new InternalErrorException(e);
        } finally {
            GeneralOperations.closeStatement(preparedStatement);
        }
        
	}



//	encontrar una linea de pedido  



	public LineaPedidoTO find(Connection connection, int idLineaPedido) 
	throws InternalErrorException {

		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;

		try {


			/* Create "preparedStatement". */
			String queryString = "SELECT IDPEDIDO, IDLINEA, NUMUNIDADES, PRECIO, ESTADO, IDPRODUCTO FROM LINEAPEDIDO" + " WHERE IDLINEA = ?";
			preparedStatement = connection.prepareStatement(queryString);    

			/* Fill "preparedStatement". */
			int i = 1;
			preparedStatement.setInt(i++, 
					idLineaPedido);

			/* Execute query. */
			resultSet = preparedStatement.executeQuery();

			if (!resultSet.next()) {
				throw new InternalErrorException(new SQLException(
						"No hay ninguna linea de pedido con ese identificador."));
			}

			/* get result */
			i = 1;
			int idPedido= resultSet.getInt(i++);
			int idLinea= resultSet.getInt(i++);
			int numUnidades= resultSet.getInt(i++);
			int precio= resultSet.getInt(i++);
			String estado= resultSet.getString(i++);
			int idProducto= resultSet.getInt(i++);

			return new LineaPedidoTO(idPedido, idLinea, numUnidades, precio, estado, idProducto);

		} catch (SQLException e) {
			throw new InternalErrorException(e);
		} finally {
			GeneralOperations.closeStatement(preparedStatement);
			GeneralOperations.closeResultSet(resultSet);
		}

	}


	/* encontrar una lista de productos de un idPedido */

	public List<LineaPedidoTO> findByIdPedido(Connection conexion, int idPedido, int inicio, int elemPorGrupo) 
	throws InternalErrorException {



		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;

		try {

			/* Create "preparedStatement". */

			String queryString = "SELECT IDPEDIDO, IDLINEA, NUMUNIDADES, PRECIO, ESTADO, IDPRODUCTO FROM LINEAPEDIDO" + " WHERE IDPEDIDO = ?";
			preparedStatement = conexion.prepareStatement(queryString);


			/* Fill "preparedStatement". */
			int i = 1;
			preparedStatement.setInt(i++, idPedido);


			/* Execute query. */
			resultSet = preparedStatement.executeQuery();

			/* Read objects. */
			List<LineaPedidoTO> lineaPedidoTOs = new ArrayList<LineaPedidoTO>();
			int contador = 0;

			if ((inicio >=1) && resultSet.absolute(inicio)) {

				do {

					i = 1;
					int idPed= resultSet.getInt(i++);
					int idLinea= resultSet.getInt(i++);
					int numUnidades= resultSet.getInt(i++);
					int precio= resultSet.getInt(i++);
					String estado= resultSet.getString(i++);
					int idProducto= resultSet.getInt(i++);

					lineaPedidoTOs.add(new LineaPedidoTO(idPed, idLinea, numUnidades, precio, estado, idProducto));

					contador++;


				} while (resultSet.next() && (contador < elemPorGrupo)) ;

			}

			/* Return value objects. */                
			return lineaPedidoTOs;

		} catch (SQLException e) {
			throw new InternalErrorException(e);    
		} finally {
			GeneralOperations.closeResultSet(resultSet);
			GeneralOperations.closeStatement(preparedStatement);
		}

	}

	
	
	
	public List findPendientes(Connection connection,int idPedido) 
    throws InternalErrorException {
    
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    List listaIdLinea = new ArrayList(); 
    
    try {
            

        /* Create "preparedStatement" para devolver la lista de idPedidos pendientes. */
        String queryString = "SELECT IDLINEA FROM LINEAPEDIDO WHERE IDPEDIDO= ? AND ESTADO = 'PENDIENTE'";
        preparedStatement = connection.prepareStatement(queryString);    
        
        preparedStatement.setInt(1,idPedido);
        /* Execute query. */
		resultSet = preparedStatement.executeQuery();

        if (!resultSet.next()) {
         //   throw new InternalErrorException(new SQLException(
         //       "No hay ningun detalle de pedido con ese identificador."));
        	return null;
        }
        int contador = 0;
        int idLinea;
        do {
           		idLinea= resultSet.getInt(1);
         		
           		listaIdLinea.add(idLinea);

           		contador++;
        } while (resultSet.next()) ;
            
		/* get result */
        
		return listaIdLinea;
    
    } catch (SQLException e) {
        throw new InternalErrorException(e);
    } finally {
        GeneralOperations.closeStatement(preparedStatement);
		GeneralOperations.closeResultSet(resultSet);
    }
    
}
	
	
	
	

	/*Actualiza el estado de una linea de un pedido determinado*/

	public void actualizaEstado(Connection conexion,int idLinea) 
	throws InternalErrorException,InstanceNotFoundException {



		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		ResultSet resultSet2 = null;

		try {

			/* Create "preparedStatement" para sacar el idProducto y el numero de unidades del mismo de la linea de pedido. */

			String queryString = "SELECT NUMUNIDADES,IDPRODUCTO FROM LINEAPEDIDO" + " WHERE IDLINEA = ?";
			preparedStatement = conexion.prepareStatement(queryString);


			/* Fill "preparedStatement". */
			int i = 1;
			preparedStatement.setInt(i++, idLinea);
			
			/* Execute query. */
			resultSet = preparedStatement.executeQuery();

			resultSet.next();
			/* Read objects. */
			i = 1;
			int udads;
			udads = resultSet.getInt(i++);
			int idProducto; 
			idProducto=resultSet.getInt(i++);
			
			
			/* Create "preparedStatement" para sacar el stock del producto de la tabla de pedidos. */

			String queryString2 = "SELECT STOCK FROM PRODUCTO" + " WHERE IDPRODUCTO = ?";
			preparedStatement = conexion.prepareStatement(queryString2);


			/* Fill "preparedStatement". */
			i=1;
			preparedStatement.setInt(i++, idProducto);


			/* Execute query. */
			
			resultSet2 = preparedStatement.executeQuery();
			resultSet2.next();
			/* Read objects. */
			i=1;
			int stock=0;
			stock= resultSet2.getInt(i++);
			
			/*Calculamos el numero de unidades que quedarian del producto si servimos la linea de pedido*/
			int nStock=stock-udads;
			
			/*Si el numero de unidades que nos quedan es positivo->la servimos*/

			if (nStock>0) {


				preparedStatement = conexion.prepareStatement("UPDATE PRODUCTO " +
				"SET STOCK = ? WHERE IDPRODUCTO = ? ");
				preparedStatement.setInt(1,nStock);
				preparedStatement.setInt(2,idProducto);
				

				if (preparedStatement.executeUpdate()!=1)
					throw new SQLException("Error actualizando stock en " +
							"idProducto '"+idProducto+"'");
				
				preparedStatement = conexion.prepareStatement("UPDATE LINEAPEDIDO" +
				" SET ESTADO = ? WHERE IDLINEA = ?");

				preparedStatement.setString(1,"LISTO");
				preparedStatement.setInt(2,idLinea);

				int updatedRows = preparedStatement.executeUpdate();
		
				if (updatedRows == 0) {
					throw new InstanceNotFoundException(idLinea,"SQLLineaPedidoDAO");
				}

				if (updatedRows > 1) {
					throw new SQLException("Duplicate row for identifier = '" + 
							idLinea + "' in table 'LINEAPEDIDO'");
				}        


			};

		} catch (SQLException e) {
			throw new InternalErrorException(e);    
		} finally {
			GeneralOperations.closeResultSet(resultSet);
			GeneralOperations.closeStatement(preparedStatement);
		}

	}


}
